{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0c62b241",
   "metadata": {},
   "source": [
    "# 第五讲 数字数据类型\n",
    "\n",
    "## 1. 数字 (Numbers)\n",
    "在编程中，经常使用数（number）来记录得分、表示可视化数据、存储信息等等。Python根据数的用法以不同的方式处理它们。鉴于整数使用起来最简单，下面就先来看看Python是如何管理它们的。\n",
    "\n",
    "## 2. 整数 (Integers)\n",
    "在Python中，可对整数（integer）执行加（+）减（-）乘（*）除（/）运算。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "50e8d324",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5 3 12 4.0\n",
      "8 25 64 2.8284271247461903\n",
      "14\n",
      "20\n"
     ]
    }
   ],
   "source": [
    "# 整数四则运算\n",
    "print(2+3, 5-2, 4*3, 8/2)\n",
    "\n",
    "# 整数乘方运算\n",
    "print(2**3, 5**2, 4**3, 8**(1/2))\n",
    "\n",
    "# 运算顺序\n",
    "print(2 + 3 * 4)      # 乘法优先\n",
    "print((2 + 3) * 4)    # 括号改变优先"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e169f82d",
   "metadata": {},
   "source": [
    "**注意：** 在这些示例中，空格不影响Python计算表达式的方式。它们旨在让你在阅读代码时，能迅速确定将先执行哪些运算。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6499766",
   "metadata": {},
   "source": [
    "## 3. 浮点数 (Floats)\n",
    "Python将带小数点的数称为浮点数（float）。大多数编程语言使用了这个术语，它指出了这样一个事实：小数点可出现在数的任何位置上。每种编程语言都必须细心设计，以妥善地处理浮点数，确保不管小数点出现在什么位置上，数的运算都是正确的。\n",
    "\n",
    "从很大程度上说，使用浮点数时无须考虑其行为。你只需输入要使用的数，Python通常会按你期望的方式处理它们："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0446254b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5.0 3.0 12.0 4.0\n",
      "8.0 25.0 64.0 2.8284271247461903\n",
      "14.0\n",
      "20.0\n"
     ]
    }
   ],
   "source": [
    "# 浮点数的四则运算和乘方运算\n",
    "print(2.0 + 3.0, 5.0 - 2.0, 4.0 * 3.0, 8.0 / 2.0)\n",
    "print(2.0**3.0, 5.0**2.0, 4.0**3.0, 8.0**(1/2.0))   \n",
    "print(2.0 + 3.0 * 4.0)      # 乘法优先\n",
    "print((2.0 + 3.0) * 4.0)    # 括号改变优先"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e9c2c363",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.30000000000000004\n",
      "False\n",
      "5.551115123125783e-17\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "# 浮点数精度\n",
    "print(0.1 + 0.2)  # 结果不是0.3\n",
    "print(0.1 + 0.2 == 0.3)  \n",
    "print(0.1 + 0.2 - 0.3)  # 结果是一个非常小的数，而不是0.0\n",
    "print((0.1 + 0.2) - 0.3 == 0.0)   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00375e10",
   "metadata": {},
   "source": [
    "**重要说明：**\n",
    "\n",
    "- 所有编程语言都存在这种问题，没有什么可担心的\n",
    "- Python会尽力找到一种精确地表示结果的方式，但鉴于计算机内部表示数字的方式，这在有些情况下很难\n",
    "- 就现在而言，暂时忽略多余的小数位数即可\n",
    "- 在实际项目中，你将学习处理多余小数位的方式"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da169c30",
   "metadata": {},
   "source": [
    "## 4. 整数和浮点数的混合运算\n",
    "### 4.1 除法运算\n",
    "将任意两个数相除，结果总是浮点数，即便这两个数都是整数且能整除："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a5fabe71",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "4/2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "285c2e37",
   "metadata": {},
   "source": [
    "### 4.2 混合运算规则\n",
    "在其他任何运算中，如果一个操作数是整数，另一个操作数是浮点数，结果也总是浮点数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "44bb2498",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5.0\n",
      "5.0\n",
      "6.0\n",
      "6.0\n",
      "8.0\n",
      "8.0\n",
      "14.0\n",
      "20.0\n"
     ]
    }
   ],
   "source": [
    "# 整数和浮点数混合运算\n",
    "print(2 + 3.0)\n",
    "print(2.0 + 3.0)\n",
    "print(2 * 3.0)\n",
    "print(2.0 * 3.0)\n",
    "print(2**3.0)\n",
    "print(2.0**3.0)\n",
    "print(2 + 3 * 4.0)\n",
    "print((2 + 3) * 4.0)   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb49bbad",
   "metadata": {},
   "source": [
    "## 5. 数中的下划线\n",
    "在书写很大的数时，可使用下划线将其中的位分组，使其更清晰易读："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c3cc9a3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "14000000000\n"
     ]
    }
   ],
   "source": [
    "# 数中的下划线\n",
    "universe_age = 14_000_000_000\n",
    "print(universe_age) #当你打印这种使用下划线定义的数字时，Python不会打印其中的下划线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "070632e0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "3.141592653589793\n"
     ]
    }
   ],
   "source": [
    "# 以下写法都是等价的\n",
    "million1 = 1000000\n",
    "million2 = 1_000_000\n",
    "million3 = 10_00_000\n",
    "million4 = 100_0000\n",
    "print(million1==million2==million3==million4)\n",
    "\n",
    "# 浮点数也可以使用\n",
    "pi = 3.141_592_653_589_793\n",
    "print(pi)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6ba768d",
   "metadata": {},
   "source": [
    "### 使用规则\n",
    "\n",
    "- 在存储这种数时，Python会忽略其中的下划线\n",
    "- 在对数字位分组时，即便不是将每三位分成一组，也不会影响最终的值\n",
    "- 在Python看来，`1000`与`1_000`没什么不同，`1_000`与`10_00`也没什么不同\n",
    "- 这种表示法既适用于整数，也适用于浮点数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1956cc3c",
   "metadata": {},
   "source": [
    "## 6. 同时给多个变量赋值\n",
    "可在一行代码中给多个变量赋值，这有助于缩短程序并提高其可读性。这种做法最常用于将一系列数赋给一组变量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "5d800d5a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 0 0\n"
     ]
    }
   ],
   "source": [
    "x, y, z = 0, 0, 0\n",
    "print(x, y, z)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b486ec6",
   "metadata": {},
   "source": [
    "### 使用规则\n",
    "\n",
    "- 需要用逗号将变量名分开\n",
    "- 对于要赋给变量的值，也需要做同样的处理\n",
    "- Python将按顺序将每个值赋给对应的变量\n",
    "- 只要变量数和值的个数相同，Python就能正确地将变量和值关联起来"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "9d8b59f5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3\n",
      "张三 25 1.75\n",
      "20 10\n"
     ]
    }
   ],
   "source": [
    "# 更多示例\n",
    "# 同时赋值不同的数\n",
    "a, b, c = 1, 2, 3\n",
    "print(a, b, c)\n",
    "\n",
    "# 同时赋值不同类型的数据\n",
    "name, age, height = \"张三\", 25, 1.75\n",
    "print(name, age, height)\n",
    "\n",
    "# 交换变量值\n",
    "x, y = 10, 20\n",
    "x, y = y, x  # 现在 x=20, y=10\n",
    "print(x, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5542acf",
   "metadata": {},
   "source": [
    "## 7. 常量 (Constants)\n",
    "常量（constant）是在程序的整个生命周期内都保持不变的变量。\n",
    "\n",
    "Python中的常量:\n",
    "- Python没有内置的常量类型\n",
    "- 但Python程序员会使用全大写字母来指出应将某个变量视为常量\n",
    "- 其值应始终不变"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "5a733cc6",
   "metadata": {},
   "outputs": [],
   "source": [
    "MAX_CONNECTIONS = 5000\n",
    "PI = 3.14159\n",
    "SPEED_OF_LIGHT = 299792458  # 米/秒"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ffa8f9ab",
   "metadata": {},
   "source": [
    "在代码中，要指出应将特定的变量视为常量，可将其变量名全大写。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "859e2e5f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数学常量\n",
    "PI = 3.141592653589793\n",
    "E = 2.718281828459045\n",
    "\n",
    "# 配置常量\n",
    "MAX_USERS = 1000\n",
    "DEFAULT_TIMEOUT = 30\n",
    "DATABASE_URL = \"localhost:5432\"\n",
    "\n",
    "# 物理常量\n",
    "GRAVITY = 9.8  # 重力加速度 m/s²\n",
    "ABSOLUTE_ZERO = -273.15  # 绝对零度 °C"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c9ae5433",
   "metadata": {},
   "source": [
    "## 8. 最佳实践"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88f72934",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1. 数字格式化输出\n",
    "# 控制小数位数\n",
    "pi = 3.141592653589793\n",
    "print(f\"{pi:.2f}\")  # 输出: 3.14\n",
    "print(f\"{pi:.4f}\")  # 输出: 3.1416\n",
    "\n",
    "# 千位分隔符\n",
    "big_number = 1234567\n",
    "print(f\"{big_number:,}\")  # 输出: 1,234,567"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "baddb44d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 2. 数学运算函数\n",
    "import math\n",
    "\n",
    "# 常用数学函数\n",
    "print(math.sqrt(16))    # 平方根: 4.0\n",
    "print(math.pow(2, 3))   # 幂运算: 8.0\n",
    "print(math.ceil(4.2))   # 向上取整: 5\n",
    "print(math.floor(4.8))  # 向下取整: 4\n",
    "print(abs(-5))          # 绝对值: 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "abfac894",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 3. 数字类型转换\n",
    "# 字符串转数字\n",
    "str_num = \"123\"\n",
    "int_num = int(str_num)      # 转为整数\n",
    "float_num = float(str_num)  # 转为浮点数\n",
    "\n",
    "# 数字转字符串\n",
    "num = 456\n",
    "str_num = str(num)\n",
    "\n",
    "# 浮点数转整数\n",
    "float_val = 3.8\n",
    "int_val = int(float_val)  # 结果: 3 (截断，不是四舍五入)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "2a057c59",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数字相等\n"
     ]
    }
   ],
   "source": [
    "# 4. 数字比较\n",
    "# 浮点数比较注意事项\n",
    "a = 0.1 + 0.2\n",
    "b = 0.3\n",
    "\n",
    "# 不推荐的比较方式\n",
    "# if a == b:  # 可能为False，因为浮点数精度问题\n",
    "\n",
    "# 推荐的比较方式\n",
    "epsilon = 1e-10\n",
    "if abs(a - b) < epsilon:\n",
    "  print(\"数字相等\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "abe0dd40",
   "metadata": {},
   "source": [
    "## 9. 练习题\n",
    "\n",
    "### 9.1 基础练习\n",
    "\n",
    "1. 计算 `2 ** 10` 的值\n",
    "2. 计算 `(5 + 3) * 2 - 1` 的值\n",
    "3. 将数字 `1234567890` 用下划线分组，提高可读性\n",
    "\n",
    "### 9.2 进阶练习\n",
    "\n",
    "1. 编写代码同时给三个变量赋值：圆的半径为5，π为3.14159，计算圆的面积\n",
    "2. 定义常量表示一年的天数、小时数、分钟数和秒数\n",
    "3. 处理浮点数精度问题：比较 `0.1 + 0.1 + 0.1` 和 `0.3` 是否相等\n",
    "\n",
    "### 9.3 实际应用\n",
    "\n",
    "1. 计算复利：本金10000元，年利率5%，存款10年后的金额\n",
    "2. 单位转换：将温度从摄氏度转换为华氏度（公式：F = C × 9/5 + 32）\n",
    "3. 计算BMI指数：体重70kg，身高1.75m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d1bc853",
   "metadata": {},
   "source": [
    "## 10. 总结\n",
    "\n",
    "### 10.1 关键要点\n",
    "\n",
    "1. **整数运算**：支持基本四则运算和乘方运算\n",
    "2. **浮点数**：带小数点的数，存在精度问题\n",
    "3. **混合运算**：有浮点数参与的运算结果总是浮点数\n",
    "4. **下划线分组**：提高大数字的可读性\n",
    "5. **多变量赋值**：一行代码给多个变量赋值\n",
    "6. **常量约定**：使用全大写字母表示常量\n",
    "\n",
    "### 10.2 注意事项\n",
    "\n",
    "- 浮点数计算可能存在精度误差\n",
    "- 除法运算总是返回浮点数\n",
    "- 使用下划线分组数字时，输出不会显示下划线\n",
    "- 常量只是约定，Python不会强制其不变性\n",
    "\n",
    "### 10.3 最佳实践\n",
    "\n",
    "- 合理使用空格提高代码可读性\n",
    "- 大数字使用下划线分组\n",
    "- 常量使用全大写命名\n",
    "- 浮点数比较时考虑精度问题\n",
    "- 选择合适的数据类型存储数值"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
